;(function($){

$.fn.datePicker = function(){
	new $.ui.datepicker(this.id);
}

$.ui = $.ui || {};

$.ui.datepicker = function(id) {
    this.Z_INDEX_FLOOR = 301;
    this.NUM_ROWS = 6;

    this.modes = {
        INPUT: 0, // bound to an input field (like in event form)
        POPUP: 1, // popup when something is clicked (calendar navigation)
        STATIC: 2 // display inline in page (like cal_share page)
    };

    this.STYLE_ERROR_COLOR = "#FFC0CB";

    this._dayArray = ['日', '一', '二', '三', '四', '五', '六'];

    this._widgetId = id;
    this._widget = null;
    this._blurTimer = null;
    this._selectedDate = null;
    this._currentMonthFocus = new Date();
    this._currentMonthFocus.setDate(1);
    this._popupOpen = false;
    this._today = new Date();
    this._validDate = true;
    this._mode = null;
    this._popupDiv = null;
    this._containerDiv = null;
    var self = this;

    this._contentDiv = document.createElement('div');
    $(this._contentDiv).attr("id", this._widgetId).click(function(evt) {
        clearTimeout(self._blurTimer);
        evt.stopPropagation();
    });
};

$.ui.datepicker.prototype = {
    bindInput: function(inputTarget, container) {
        this._mode = this.modes.INPUT;
        this._inputTarget = inputTarget;
        this._containerDiv = container;
        this._containerDiv.className = 'datePickerContainer';
        this._popupDiv = document.createElement('div');
        this._popupDiv.className = 'datePickerPopup';
        this._popupDiv.appendChild(this._contentDiv);
        this._containerDiv.appendChild(this._popupDiv);
        $(this._popupDiv).hide();
        var self = this;
        $(this._inputTarget).click(function(e) {
            if (self._popupOpen) {
                self.close();
            } else {
                self.open();
            }
            e.stopPropagation();
        }).blur(function(e) {
            self._blurTimer = setTimeout((function() {
                self.close();
            }), 200);
        }).change(function(e) {
            self._parseInput();
        }).keydown(function(e) {
            self._handleKeyDown(e);
        })
        this._initClickToClose();
    },
    bindPopup: function(popupTarget, container) {
        this._mode = this.modes.POPUP;
        this._popupTarget = popupTarget;
        this._containerDiv = container;
        this._containerDiv.className = 'datePickerContainer';
        this._popupDiv = document.createElement('div');
        this._popupDiv.className = 'datePickerPopup';
        this._popupDiv.appendChild(this._contentDiv);
        this._containerDiv.appendChild(this._popupDiv);
        $(this._popupDiv).hide();
        var self = this;
        $(this._popupTarget).click(function(e) {
            if (self._popupOpen) {
                self.close();
            } else {
                self.open();
            }
            e.stopPropagation();
        });
        this._initClickToClose();
    },
    bindStatic: function(container) {
        this._mode = this.modes.STATIC;
        this._containerDiv = container;
        this._containerDiv.className = 'datePickerContainer';
        this._containerDiv.appendChild(this._contentDiv);
        this._popupOpen = true;
        this.render();
    },
    open: function() {
        this._popupOpen = true;
        var newFocus = this._selectedDate || new Date();
        this._currentMonthFocus.setMonth(newFocus.getMonth());
        this._currentMonthFocus.setFullYear(newFocus.getFullYear());
        this.render();
        if (this._containerDiv) this._containerDiv.style.zIndex = this.Z_INDEX_FLOOR;
        $(this._popupDiv).show();
        HtmlUtils.enableIFrame(this._popupDiv);
    },
    close: function() {
        this._popupOpen = false;
        if (this._containerDiv) this._containerDiv.style.zIndex = '';
        $(this._popupDiv).hide();
        HtmlUtils.hideIFrame();
        //plaxo.ui.html.style.hideit(this._popupDiv);
    },
    render: function() {
        if (!this._contentDiv.innerHTML) {
            this._initContent();
        }
        var todayKey = DateMath.toKey(this._today);
        var focusMonth = this._currentMonthFocus.getMonth();
        var loopDate = this._getFirstDayOfWeek(this._currentMonthFocus);
        this._monthNameHandle.innerHTML = this._currentMonthFocus.getFullYear() + "年" + this._currentMonthFocus.getMonth() + "月";

        for (var i = 0; i < this._monthGridCells.length; i++,loopDate = DateMath.add(loopDate, DateMath.DAY, 1)) {
            var cell = this._monthGridCells[i];
            cell.innerHTML = loopDate.getDate();
            var loopDateKey = DateMath.toKey(loopDate);
            if (loopDateKey == todayKey) {
                $(cell).addClass("today");
            } else {
                $(cell).removeClass("today");
            }
            if (loopDate.getMonth() != focusMonth) {
                $(cell).addClass('adjacentMonth');
            } else {
                $(cell).removeClass('adjacentMonth')
            }
        }
        this._updateSelectedDate();
    },
    getSelectedDate: function() {
        return this._selectedDate ? new Date(this._selectedDate) : null;
    },
    setSelectedDate: function(dateObj) {
        this._selectedDate = dateObj;
        this._validDate = true;
        this._currentMonthFocus.setMonth(this._selectedDate.getMonth());
        this._currentMonthFocus.setFullYear(this._selectedDate.getFullYear());
        if (this._popupOpen) this.render();
        if (this._inputTarget) this._updateInputBox();
    },
    getCurrentMonth: function() {
        return new Date(this._currentMonthFocus);
    },
    reset: function() {
        this._selectedDate = null;
        this._currentMonthFocus = new Date();
        this._currentMonthFocus.setDate(1);
        this._validDate = true;
        if (this._popupOpen) this.render();
        if (this._inputTarget) {
            this._inputTarget.value = "";
            this._inputTarget.style.backgroundColor = "";
        }
    },
    validDate: function() {
        return this._validDate;
    },
    onDateChange: function() {
    },
    onMonthChange: function() {
    },
    _initClickToClose: function() {
        var self = this;
        $(document).bind('click', function(e) {
            if (self._popupOpen) self.close();
        });
    },
    _getFirstDayOfWeek: function(dateObj) {
        return DateMath.findFirstDayOfWeek(dateObj);
    },
    _updateSelectedDate: function() {
        for (var i = 0; i < this._monthGridCells.length; i++) {
            $(this._monthGridCells[i]).removeClass('selected');
        }
        if (this._selectedDate) {
            var firstDay = this._getFirstDayOfWeek(this._currentMonthFocus);
            var todayIndex = DateMath.daysBetween(this._today, firstDay);
            var daysBetween = DateMath.daysBetween(this._selectedDate, firstDay);
            if (0 <= daysBetween && daysBetween < this.NUM_ROWS * 7 && daysBetween != todayIndex) {
                $(this._monthGridCells[daysBetween]).addClass('selected');
                $(this._monthGridCells[daysBetween]).removeClass('hover');
            }
        }
    },
    _initContent: function() {
        var h = [];
        var i = 0;
        h.push('<div class="datePickerContent">');
        h.push('<div class="month">');
        h.push('<div class="header"><table width="100%" cellspacing="0" cellpadding="0"><tr>');
        h.push('<td width="20"><span class="previous"><img src="images/arrow_left.gif"></span></td>');
        h.push('<td width="20"><span class="next"><img src="images/arrow_right.gif"></span></td>');
        h.push('<td class="monthName">&nbsp;</td>');
        if (this._mode != this.modes.STATIC) {
            h.push('<td width="20" align="right"><div class="closeX"><img src="images/close.png"></div></td>');
        }
        h.push('</tr></table></div>');
        h.push('<table width="100%" class="grid" cellpadding="0" cellspacing="0">');
        h.push('<tr class="dow">');
        for (i = 0; i < 7; i++) {
            h.push('<td>' + this._dayArray[i] + '</td>');
        }
        h.push('</tr>');
        for (i = 0; i < this.NUM_ROWS; i++) {
            h.push('<tr>');
            for (var d = 0; d < 7; d++) {
                h.push('<td valign="middle"><div class="day">&nbsp;</div></td>');
            }
            h.push('</tr>');
        }
        h.push('</table>');
        h.push('</div>');
        h.push('</div>');
        this._contentDiv.innerHTML = h.join('');
        var self = this;
        this._monthNameHandle = $("td.monthName", $(this._contentDiv))[0];
        this._monthGrid = $("table.grid", $(this._contentDiv))[0];
        var previousMonthHandle = $("span.previous", $(this._contentDiv))[0];
        previousMonthHandle.onclick = function(evt) {
            self._handleDoPreviousMonth(evt);
        };
        var nextMonthHandle = $("span.next", $(this._contentDiv))[0];
        nextMonthHandle.onclick = function(evt) {
            self._handleDoNextMonth(evt);
        };
        if (this._mode != this.modes.STATIC) {
            $("div.closeX", $(this._contentDiv)).click(function(e) {
                self.close();
            });
        }


        this._monthGridCells = $("div.day", $(this._monthGrid));
        this._monthGridCells.each(function(i, e) {
            $(this).attr('index', i).click(function(e) {
                self._handleDateSelect(e);
            }).mouseover(function(e) {
                self._handleCellMouseover(e);
            }).mouseout(function(e) {
                self._handleCellMouseout(e);
            });
        });
    },
    _updateInputBox: function() {
        if (this._selectedDate === null && this._validDate) {
            this._inputTarget.value = '';
        } else if (this._selectedDate !== null) {
            this._inputTarget.value = StringFormatter.format('{0}/{1}/{2}', this._selectedDate.getFullYear(), this._selectedDate.getMonth(), this._selectedDate.getDate());
        }
        this._inputTarget.style.backgroundColor = this._validDate ? "" : this.STYLE_ERROR_COLOR;
    },
    _handleDateSelect: function(evt) {
        var newSelection = this._getFirstDayOfWeek(this._currentMonthFocus);
        var selectedIndex = parseInt(evt.target.getAttribute('index'), 10);
        newSelection = DateMath.add(newSelection, DateMath.DAY, selectedIndex);
        //plaxo.util.date.addDays(newSelection, selectedIndex);
        this._selectedDate = new Date(newSelection);
        this._validDate = true;
        this._updateSelectedDate();
        if (this._inputTarget) {
            this._updateInputBox();
            this._inputTarget.focus();
        }
        if (this._popupDiv) this.close();
        this.onDateChange();
    },
    _handleDoPreviousMonth: function(evt) {
        this._currentMonthFocus.setMonth(this._currentMonthFocus.getMonth() - 1);
        if (this._popupOpen) this.render();
        this.onMonthChange();
    },
    _handleDoNextMonth: function(evt) {
        this._currentMonthFocus.setMonth(this._currentMonthFocus.getMonth() + 1);
        if (this._popupOpen) this.render();
        this.onMonthChange();
    },
    _parseInput: function() {
        var value = this._inputTarget.value;
        if (value) {
            var date = value //plaxo.i18n.parseDate(value);
            if (date !== null) {
                this.setSelectedDate(date);
                this.onDateChange();
                this._validDate = true;
            } else {
                this._selectedDate = null;
                this._validDate = false;
            }
        } else {
            this._selectedDate = null;
            this._validDate = true; // no date entered is a valid state
        }
        this._updateInputBox();
    },
    _handleCellMouseover: function(evt) {
        if ($(evt.target).hasClass('selected')) {
            $(evt.target).addClass('hover');
        }
    },
    _handleCellMouseout: function(evt) {
        $(evt.target).removeClass('hover');
    },
    _handleKeyDown: function(evt) {
        var byHour = !evt.ctrlKey;
        var keyCode = evt.keyCode;
        var newSelection = new Date(this._selectedDate);
        var usedEvent = true;
        if (!this._popupOpen) return;
        if (keyCode == 38) {
            DateMath.subtract(newSelection, DateMath.DAY, 7);
            this.setSelectedDate(newSelection);
        } else if (keyCode == 40) {
            DateMath.add(newSelection, DateMath.DAY, 7);
            this.setSelectedDate(newSelection);
        } else if (keyCode == 37) {
            if (evt.ctrlKey) {
                newSelection.setMonth(newSelection.getMonth() - 1);
                this.setSelectedDate(newSelection);
            } else {
                DateMath.subtract(newSelection, DateMath.DAY, -1);
                this.setSelectedDate(newSelection);
            }
        } else if (keyCode == 39) {
            if (evt.ctrlKey) {
                newSelection.setMonth(newSelection.getMonth() + 1);
                this.setSelectedDate(newSelection);
            } else {
                DateMath.add(newSelection, DateMath.DAY, 1);
                this.setSelectedDate(newSelection);
            }
        } else if (keyCode == 13 || keyCode == 27) {
            this._parseInput();
            this.close();
        } else {
            usedEvent = false;
        }
        if (usedEvent) {
            evt.stop();
        }
    }
};
})(jQuery);